/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.compomics.dataprovider.control;

import com.compomics.dataprovider.control.logic.fasta.FastaSourceConverter;
import com.compomics.dataprovider.control.logic.fasta.UniprotFastaProvider;
import com.compomics.dataprovider.model.fasta.FastaStream;
import com.compomics.util.gui.waiting.waitinghandlers.WaitingDialog;
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;

/**
 *
 * @author Kenneth
 */
public class GUIExecutor extends CLIExecutor {

    private final WaitingDialog dialog;

    public GUIExecutor(WaitingDialog dialog) {
        super();
        this.dialog = dialog;
    }

    private int getAmountOfSteps() {
        int steps = 0;
        if (filesToMerge != null) {
            steps++;
        }
        if (taxonomiesToDownload != null) {
            steps++;
        }
        if (is_rem_dup_seq) {
            steps++;
        }
        if (is_rem_dup_acc) {
            steps++;
        }
        if (isCrap) {
            steps++;
        }
        if (isDecoy) {
            steps++;
        }
        return steps;
    }

    @Override
    public boolean execute() throws IOException {
        Thread workingThread = new Thread(getWorkingThread(dialog));
        workingThread.start();
        dialog.setVisible(true);
        while (!dialog.isRunFinished()) {
            if (dialog.isRunCanceled() || workingThread.isAlive()) {
                workingThread.interrupt();
                dialog.appendReport("Process was interrupted...", true, true);
                break;
            }
        }
        int dialogButton = JOptionPane.YES_NO_OPTION;
        int dialogResult = JOptionPane.showConfirmDialog(dialog, "Would you like to make more FASTA-files?", "Continue?", dialogButton);
        if (dialogResult == 0) {
            return true;
        } else {
            return false;
        }
    }

    public Runnable getWorkingThread(final WaitingDialog dialog) {
        return new Runnable() {
            @Override
            public void run() {
                try {
                    FastaStream stream = new FastaStream(FastaSourceConverter.convertToStream(outputFile));
                    int stepsDone = 0;
//first do the local concatenation
                    int i = 0;
                    if (filesToMerge != null) {
                        dialog.appendReport("Processing files...", true, true);
                        dialog.setMaxPrimaryProgressCounter(getAmountOfSteps());
                        dialog.setMaxSecondaryProgressCounter(filesToMerge.size());
                        for (String aFile : filesToMerge) {
                            try {
                                dialog.appendReport(i + ". Processing " + aFile, true, true);
                                stream.concatenate(new File(aFile));
                                i++;
                                dialog.setSecondaryProgressCounter(i);
                            } catch (IOException ex) {
                                Logger.getLogger(GUIExecutor.class.getName()).log(Level.SEVERE, null, ex);
                            }
                        }
                        stepsDone++;
                        dialog.setMaxPrimaryProgressCounter(stepsDone);
                    }
                    //merge the URLs
                    int j = 0;
                    if (taxonomiesToDownload != null) {
                        dialog.setSecondaryProgressCounter(0);
                        dialog.setMaxSecondaryProgressCounter(taxonomiesToDownload.size());
                        for (Map.Entry<String, String> aTaxonomy : taxonomiesToDownload.entrySet()) {
                            dialog.appendReport(i + j + ". Downloading fasta for taxonomyID " + aTaxonomy.getKey() + "[" + aTaxonomy.getValue() + "]", true, true);
                            UniprotFastaProvider.downloadFastaToStream(stream, aTaxonomy.getKey(), aTaxonomy.getValue(), isReviewOnly);
                            j++;
                            dialog.setSecondaryProgressCounter(j);
                        }
                        stepsDone++;
                        dialog.setMaxPrimaryProgressCounter(stepsDone);
                    }
                    //remove duplicats
                    if (is_rem_dup_seq) {
                        dialog.appendReport("Removing duplicate sequences", true, true);
                        dialog.setSecondaryProgressCounterIndeterminate(true);
                        stream.removeDuplicateSequences();
                        dialog.setSecondaryProgressCounterIndeterminate(false);
                        dialog.setSecondaryProgressCounter(0);
                        stepsDone++;
                        dialog.setMaxPrimaryProgressCounter(stepsDone);
                    }
                    if (is_rem_dup_acc) {
                        dialog.appendReport("Removing duplicate accessions", true, true);
                        dialog.setSecondaryProgressCounterIndeterminate(true);
                        stream.removeDuplicateAccessions();
                        dialog.setSecondaryProgressCounterIndeterminate(false);
                        dialog.setSecondaryProgressCounter(0);
                        stepsDone++;
                        dialog.setMaxPrimaryProgressCounter(stepsDone);
                    }
                    if (isCrap) {
                        dialog.appendReport("Appending common contaminants", true, true);
                        dialog.setSecondaryProgressCounterIndeterminate(true);
                        stream.appendCRAP();
                        dialog.setSecondaryProgressCounterIndeterminate(false);
                        dialog.setSecondaryProgressCounter(0);
                        stepsDone++;
                        dialog.setMaxPrimaryProgressCounter(stepsDone);
                    }
                    if (isDecoy) {
                        dialog.appendReport("Appending decoy sequences", true, true);
                        dialog.setSecondaryProgressCounterIndeterminate(true);
                        stream.addDecoys();
                        dialog.setSecondaryProgressCounterIndeterminate(false);
                        dialog.setSecondaryProgressCounter(0);
                        stepsDone++;
                        dialog.setMaxPrimaryProgressCounter(stepsDone);
                    }
                    dialog.appendReport("Saving FASTA to file", true, true);
                    dialog.setSecondaryProgressCounterIndeterminate(true);
                    stream.save(outputFile, isAppend);
                    dialog.setSecondaryProgressCounterIndeterminate(false);
                    dialog.setPrimaryProgressCounter(getAmountOfSteps());
                    dialog.setSecondaryProgressCounter(100);
                    dialog.setRunFinished();
                } catch (IOException ex) {
                    dialog.appendReport("ERROR : " + ex, true, true);
                    dialog.setRunCanceled();
                } catch (URISyntaxException ex) {
                    Logger.getLogger(GUIExecutor.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        };
    }

}
